#pragma once

#include <memory>

#include "Containers/Containers.h"
#include "ScriptRuntime/ScriptInnerType.h"
#include "ScriptCompiler/FrameOperation/FrameOperation.h"
#include "ScriptCompiler/Description/DecoratedTypeDescription.h"

class CConstantValue;
enum class EScriptTokenType;

class CNamespaceDescription;
class CTypeDescription;
class CParameterDescription;
class CPropertyDescription;
class CFunctionDescription;
class CGSharpFieldDescription;
class IIdentifierDescription;
class CFunctionBodyDescription;
class CVariableDescription;
class CConstructorDescription;
class CFunctionBodyDescription;
class CNamespaceDescription;

class CCompilerContext;
class CScriptFileContext;
class CStatementContext;
class CExpressionContext;

class CScriptToken;

class CSentenceNode;
class CReturnNode;
class CParameterNode;
class CClassNode;
class CEnumNode;
class CDelegateNode;
class CNamespaceNode;
class CVariableDeclarationNode;
class CIdentifierNode;
class CNewNode;
class CAssignNode;
class CMemberAccessNode;
class CExpressionNode;
class CLiteralNode;
class CVariableNode;
class CBinocularOperatorNode;
class CFunctionCallNode;
class CTypeNode;
class CFunctionContext;
class CIfNode;
class CWhileNode;
class CDoWhileNode;
class CForNode;
class CBreakNode;
class CContinueNode;
class CMonocularOperatorNode;
class CSwitchNode;
class CCaseNode;
class CValueNode;
class CDoNothingOperation;
class CSentenceBlockNode;
class CExpressionSentence;
class CPositiveNode;
class CNegativeNode;
class CParenthesesNode;
class CTypeCastNode;

#include "ScriptCompiler/Description/GenericTypeArguments.h"

class CNameSearchTreeNode;

class CSemanticAnalyzer
{
public:
    void Analysis(std::shared_ptr<CCompilerContext> InContext);

    void CollectNativeClasses(std::shared_ptr<CCompilerContext> InContext);

    void CreateScriptNamespaces(std::shared_ptr<CScriptFileContext> InFileContext);

    bool CreateUsing(std::shared_ptr<CScriptFileContext> InFileContext);

    bool CreateScriptClasses(std::shared_ptr<CScriptFileContext> InFileContext);

    //create types that determaind by class head, such as delegate return and parameter types
    bool CreateClassLevelTypes(std::shared_ptr<CScriptFileContext> InFileContext);

    bool DetermineBaseClass(std::shared_ptr<CScriptFileContext> InFileContext);

    //bool FindOrAddNamespaceDescription(std::shared_ptr<CNamespaceDescription> InParentDescription, std::shared_ptr<CNamespaceNode> InNamespaceNode, std::shared_ptr<CScriptFileContext> InFileContext);
    std::shared_ptr<CTypeDescription> CreateClassDescription(const TVector<CString> &ParentNameChain, TVariant<std::shared_ptr<CTypeDescription>, std::shared_ptr<CNamespaceDescription>> ParentScope, std::shared_ptr<CClassNode> InClassNode, std::shared_ptr<CScriptFileContext> InFileContext);
    std::shared_ptr<CTypeDescription> CreateDelegateDescription(
        TVariant<std::shared_ptr<CTypeDescription>, std::shared_ptr<CNamespaceDescription>> ParentScope 
        , std::shared_ptr<CDelegateNode> InDelegateNode
        , std::shared_ptr<CScriptFileContext> InFileContext);
    std::shared_ptr<CTypeDescription> CreateEnumDescription(const TVector<CString> &ParentNameChain, TVector<std::shared_ptr<CTypeDescription>> &InOutParentEnums, std::shared_ptr<CEnumNode> InEnumNode, std::shared_ptr<CScriptFileContext> InFileContext);
 
    bool CreateClassMembers(std::shared_ptr<CScriptFileContext> InFileContext);

    bool InitConstantFields(std::shared_ptr<CScriptFileContext> InFileContext);

    // create a new class description with generic type arguments
    void GenerializeClass(
        std::shared_ptr<CTypeDescription> &OutGeneralizedClass, std::shared_ptr<CTypeDescription> Template, const SGenericTypeArgumentGroup &InArguments, std::shared_ptr<CCompilerContext> InCompilerContext);
    
    //generialize a type with generic type arguments and placeholders
    //because the placeholder might stander for a dynamic number of types, 
    //such as  a function type  ReturnType(Args...) in, the Args... is a placeholder
    //and the Args... is a type list and can be empty or have one or more types
    //so the result is a vector of types. 
    //at most time, the result only have one type
    TVector<SDecoratedTypeDescription> GenerializeType(
        SDecoratedTypeDescription TemplateType
        , const TVector<std::shared_ptr<CTypeDescription>> &InPlaceholder
        , const SGenericTypeArgumentGroup &InArguments
        , std::shared_ptr<CCompilerContext> InCompilerContext);

    std::shared_ptr<CTypeDescription> FindOrCreateScriptGenerializedClass(
        std::shared_ptr<CTypeDescription> Template, const SGenericTypeArgumentGroup &InArguments, std::shared_ptr<CCompilerContext> InCompilerContext);
    // std::shared_ptr<CTypeDescription> FindOrCreateSharedPtrClass(
    //     std::shared_ptr<CTypeDescription> ObjectClass, std::shared_ptr<CCompilerContext> InCompilerContext);

    bool InitVirtualFunctionTable(std::shared_ptr<CNamespaceDescription> InNamespace, std::shared_ptr<CCompilerContext> InCompilerContext);
    bool InitVirtualFunctionTable(std::shared_ptr<CTypeDescription> InClass, std::shared_ptr<CCompilerContext> InCompilerContext);

    bool FillFunctionBody(std::shared_ptr<CScriptFileContext> InFileContext);
    bool FillFunctionBodyWithFunctionContext(std::shared_ptr<CFunctionContext> InFunctionContext);
    bool FillConstructorBodyWithFunctionContext(std::shared_ptr<CConstructorDescription> InConstructor,std::shared_ptr<CFunctionContext> InFunctionContext);

    struct STypeDerivationResult
    {
        static STypeDerivationResult Failed()
        {
            STypeDerivationResult Result;
            Result.bIsSucceed=false;
            return Result;
        }

        virtual bool IsSucceed() const {return (bool)bIsSucceed;}
        SDecoratedTypeDescription Type;
        // if true, 
        // the Type ==nullptr;
        // the type should judge by other expression, such as "var a=1;"
        bool bIsVar=false; 

        bool bIsSucceed=true;
    };

    //a name scope is a class or a namespace
    struct SNameScopeInCompile
    {
        static SNameScopeInCompile Create(std::shared_ptr<CTypeDescription> InClass)
        {
            SNameScopeInCompile Result;
            Result.Class = InClass;
            return Result;
        }

        static SNameScopeInCompile Create(std::shared_ptr<CNamespaceDescription> InNamespace)
        {
            SNameScopeInCompile Result;
            Result.Namespace = InNamespace;
            return Result;
        }

        //find a sub name scope in this name scope
        //if not found, return NullOpt
        TOptional<SNameScopeInCompile> FindSubNameScope(
            std::shared_ptr<CScriptFileContext> InFileContext
            ,const CString& InName
            );
       
        bool IsClass() const {return (bool)Class;}
        bool IsNamespace() const {return (bool)Namespace;}

        std::shared_ptr<CTypeDescription> GetClass() const {return Class;}
    protected:
        std::shared_ptr<CTypeDescription> Class;
        std::shared_ptr<CNamespaceDescription> Namespace;
    };

    STypeDerivationResult DerivationTypeNodeWithNameScope(
        std::shared_ptr<CScriptFileContext> InFileContext
        ,const SNameScopeInCompile& InNameScope
        ,std::shared_ptr<CTypeNode> InNode);


    //get the type of a type node
    //this is not a expression
    STypeDerivationResult DerivationTypeNodeWithClass(
        std::shared_ptr<CScriptFileContext> InFileContext
        ,std::shared_ptr<CTypeDescription> InNamescope
        ,std::shared_ptr<CTypeNode> InNode);

    STypeDerivationResult DerivationTypeNodeWithNamespace(
        std::shared_ptr<CScriptFileContext> InFileContext
        ,std::shared_ptr<CNamespaceDescription> InNamescope
        ,std::shared_ptr<CTypeNode> InNode);
    
    STypeDerivationResult DerivationTypeNode(std::shared_ptr<CFunctionContext> InFunctionContext, std::shared_ptr<CTypeNode> InNode);
    
    //if type node is not a inner type node, return nullptr
    TOptional<STypeDerivationResult> DerivationInnerTypeNode(std::shared_ptr<CTypeNode> InNode);

    struct SExpressionDerivationResult
    {
        static SExpressionDerivationResult Failed()
        {
            SExpressionDerivationResult Result;
            Result.Type = SDecoratedTypeDescription();
            return Result;
        }

        virtual bool IsSucceed() const {return Type.IsValid();}
        SDecoratedTypeDescription Type;
        TVector<std::shared_ptr<IFrameOperation>> Operations;

        //if the expression is a constant, this value will be set
        TOptional<CConstantValue> ConstantValue;

    };
    SExpressionDerivationResult DerivationExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CExpressionNode> InExpression);
    SExpressionDerivationResult DerivationLiteralExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CLiteralNode> InNode);
    SExpressionDerivationResult DerivationIdentifierExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CIdentifierNode> InNode);
    SExpressionDerivationResult DerivationIdentifierExpressionWithName(std::shared_ptr<CExpressionContext> InStatementContext, const CString &InIdentifierName, std::shared_ptr<CScriptToken> InErrorToken);
    SExpressionDerivationResult DerivationBinocularOperatorExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CBinocularOperatorNode> InNode);
    
    enum class EBinocularOperatorType
    {
        Plus,
        Minus,
        Multiply,
        Divide,
        Mod,
        BitAnd,
        BitOr,
        BitXor,
        BitLeftShift,
        BitRightShift,
        LogicAnd,
        LogicOr,
        Equal,
        NotEqual,
        Greater,
        GreaterEqual,
        Less,
        LessEqual,
    };

    SExpressionDerivationResult DerivationBinocularOperatorExpressionAfterLoaded(
        std::shared_ptr<CExpressionContext> InStatementContext
        ,SDecoratedTypeDescription InLeftType
        ,SDecoratedTypeDescription InRightType
        ,EBinocularOperatorType InOperatorType
        ,std::shared_ptr<CScriptToken> InErrorToken);
    SExpressionDerivationResult DerivationNewExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CNewNode> InNode);
    SExpressionDerivationResult DerivationFunctionCallExpression(
        std::shared_ptr<CExpressionContext> InStatementContext
        , std::shared_ptr<CFunctionCallNode> InNode
        ,bool NotLoadThis  // if 'this' is already loaded, set this to true
        , std::shared_ptr<CTypeDescription> InClassDescription = nullptr);
    std::shared_ptr<CFunctionDescription> FindFunctionByExpectedTypes(
        std::shared_ptr<CExpressionContext> InExpressionContext
        , std::shared_ptr<CTypeDescription> InParentClassDescription //parent class of the function 
        , const CString &InFunctionName
        ,std::shared_ptr<CScriptToken> InErrorToken
    );

    struct SFunctionArgumentDerivationResult
    {
        static SFunctionArgumentDerivationResult Failed()
        {
            SFunctionArgumentDerivationResult Result;
            Result.FunctionIndex = -1;
            return Result;
        }

        virtual bool IsSucceed() const {return FunctionIndex!=-1;}

        TVector<std::shared_ptr<IFrameOperation>> Operations;
        int64_t FunctionIndex = -1; //first index in passed in InArgumentTypes
    };

    SFunctionArgumentDerivationResult DerivationFunctionArugments(
        const TVector<std::shared_ptr<CExpressionContext>> & InArgumentContexts
        ,const TVector<TVector<SDecoratedTypeDescription>>& InArgumentTypes //[function index][argument index]
        ,const TVector<std::shared_ptr<CExpressionNode>>& InArguments
        ,std::shared_ptr<CScriptToken> InErrorToken
    );

    SExpressionDerivationResult DerivationMonocularExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CMonocularOperatorNode> InNode);


    SExpressionDerivationResult DerivationValueExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CValueNode> InNode);
    SExpressionDerivationResult DerivationPositiveExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CPositiveNode> InNode);
    SExpressionDerivationResult DerivationNegativeExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CNegativeNode> InNode);
    SExpressionDerivationResult DerivationParenthesesExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CParenthesesNode> InNode);
    
    //left side of assign expression
    struct SLeftSideDescription
    {
        SDecoratedTypeDescription  LeftSideType;

        //operations to store left side when just store, do not load
        //such as : a=1;
        //only valid when BothLoadAndStoreLeftSide == false
        TVector<std::shared_ptr<IFrameOperation>> OnlyStoreLeftSideOperations;

        //operations to load left side when have to store later
        //such as : a+=1;
        //only valid when BothLoadAndStoreLeftSide == true
        TVector<std::shared_ptr<IFrameOperation>> LoadLeftSideOperations;
        //operations to store left side after load it
        //such as : a+=1;
        //only valid when BothLoadAndStoreLeftSide == true
        TVector<std::shared_ptr<IFrameOperation>> StoreLeftSideOperations;
    };
    
    SExpressionDerivationResult DerivationAssignExpression(std::shared_ptr<CExpressionContext> InStatementContext, std::shared_ptr<CAssignNode> InNode);
    SExpressionDerivationResult DerivationAssignExpressionWithLeftDescription(
        std::shared_ptr<CExpressionContext> InStatementContext
        , const SLeftSideDescription &  InLeft
        , std::shared_ptr<CExpressionNode> InRight
        , EScriptTokenType InOperatorType
        , std::shared_ptr<CScriptToken> ErrorToken
    );

    SExpressionDerivationResult DerivationInitializeFieldExpression(
        std::shared_ptr<CExpressionContext> InStatementContext
        , std::shared_ptr<CGSharpFieldDescription> InFiled
        , std::shared_ptr<CExpressionNode> InRight
        , std::shared_ptr<CScriptToken> ErrorToken
    );    



    SExpressionDerivationResult DerivationTypeCastExpression(
        std::shared_ptr<CExpressionContext> InStatementContext
        , std::shared_ptr<CTypeCastNode> InTypeCastNode
    );
    

    struct SMemberAccessResult : public SExpressionDerivationResult
    {
        static SMemberAccessResult Failed()
        {
            SMemberAccessResult Result;
            Result.bSuccess = false;
            Result.ClassLimitation = nullptr;
            Result.NamespaceLimitation = nullptr;
            return Result;
        }

        virtual bool IsSucceed() const { return bSuccess;}
        bool bSuccess = true;
        std::shared_ptr<CTypeDescription> ClassLimitation;
        std::shared_ptr<CNamespaceDescription> NamespaceLimitation;
    
    };

    //@ExceptLastNode : if true, the last node will not be derived
    //@Return : the type of the last derived node and class,namespace of the last node
    SMemberAccessResult DerivationMemberAccessExpression(
        std::shared_ptr<CExpressionContext> InStatementContext
        , std::shared_ptr<CMemberAccessNode> InNode
        , bool ExceptLastNode =false
    ); 

    struct SSentenceDerivationResult
    {
        static SSentenceDerivationResult Failed()
        {
            SSentenceDerivationResult Result;
            Result.bSuccess = false;
            return Result;
        }
        
        bool IsSucceed() const {return bSuccess;}
        bool bSuccess = true;
        TVector<std::shared_ptr<IFrameOperation>> Operations;
        std::shared_ptr<CStatementContext> StatementContext;
    };

    SSentenceDerivationResult DerivationSentenceBlock(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CSentenceBlockNode> InSentenceBlock);
    SSentenceDerivationResult DerivationSentence(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CSentenceNode> InSentence);
    SSentenceDerivationResult DerivationVariableDeclarationNode(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CVariableDeclarationNode> InNode);
    SSentenceDerivationResult DerivationReturnStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CReturnNode> InNode);
    SSentenceDerivationResult DerivationContinueStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CContinueNode> InNode);
    SSentenceDerivationResult DerivationBreakStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CBreakNode> InNode);
    SSentenceDerivationResult DerivationIfStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CIfNode> InNode);
    SSentenceDerivationResult DerivationWhileStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CWhileNode> InNode);

    SSentenceDerivationResult DerivationDoWhileStatement
    (
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CDoWhileNode> InNode
    );


    SSentenceDerivationResult DerivationForStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        ,std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CForNode> InNode);
    SSentenceDerivationResult DerivationSwitchStatement(
        std::shared_ptr<CFunctionContext> InFunctionContext
        , std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CSwitchNode> InNode);
    SSentenceDerivationResult DerivationExpressionSentence(
        std::shared_ptr<CFunctionContext> InFunctionContext
        , std::shared_ptr<CStatementContext> InParentStatementContext //can be null
        , std::shared_ptr<CExpressionSentence> InNode);

    bool IsStaticConvertable(SDecoratedTypeDescription To, SDecoratedTypeDescription From);
    struct SStaticConvertResult
    {
        static SStaticConvertResult Failed()
        {
            SStaticConvertResult Result;
            Result.bSuccess = false;
            return Result;
        }
        bool IsSucceed() const {return bSuccess;}
        bool bSuccess = true;
        TVector<std::shared_ptr<IFrameOperation>> Operations;
    };
    SStaticConvertResult StaticConvertTo(
        std::shared_ptr<CFunctionContext> InFunctionContext
        , SDecoratedTypeDescription To
        , SDecoratedTypeDescription From
        , std::shared_ptr<CScriptToken> ErrorToken);
    std::shared_ptr<CTypeDescription> GetNativeTypeIdentifier(CType *InType);

    bool HaveSameSignature(std::shared_ptr<CFunctionDescription> A, std::shared_ptr<CFunctionDescription> B);

    SDecoratedTypeDescription FindOrCreateFunctionType(
        SDecoratedTypeDescription InReturnType
        , TVector<SDecoratedTypeDescription> InParameters
        );

    SDecoratedTypeDescription FindOrCreateFunctionTypeWithParameter(
        SDecoratedTypeDescription InReturnType
        , TVector<std::shared_ptr<CParameterDescription>> InParameters
    );
    
    SDecoratedTypeDescription FindOrCreateDelegateType(
        SDecoratedTypeDescription InFunctionType
    );
    
protected:
    std::shared_ptr<CCompilerContext> Context;


    std::shared_ptr<CTypeDescription> GetInnerTypeClassDescription(EScriptInnerType InnerType);

    std::shared_ptr<CTypeDescription> BoolDescription;
    std::shared_ptr<CTypeDescription> ByteDescription;
    std::shared_ptr<CTypeDescription> SbyteDescription;
    std::shared_ptr<CTypeDescription> ShortDescription;
    std::shared_ptr<CTypeDescription> UshortDescription;
    std::shared_ptr<CTypeDescription> Int32Description;
    std::shared_ptr<CTypeDescription> Uint32Description;
    std::shared_ptr<CTypeDescription> Int64Description;
    std::shared_ptr<CTypeDescription> Uint64Description;
    std::shared_ptr<CTypeDescription> CharDescription;
    std::shared_ptr<CTypeDescription> FloatDescription;
    std::shared_ptr<CTypeDescription> DoubleDescription;
    std::shared_ptr<CTypeDescription> DecimalDescription;
    std::shared_ptr<CTypeDescription> StringDescription;
    std::shared_ptr<CTypeDescription> ObjectDescription;
    std::shared_ptr<CTypeDescription> NullObjectDescription; //type of null shared object ptr
    std::shared_ptr<CTypeDescription> NullPtrDescription;   //type of nullptr
    // std::shared_ptr<CTypeDescription> GenericSharedPtrDescription;
    // std::shared_ptr<CTypeDescription> GenericWeakPtrDescription;

    std::shared_ptr<CTypeDescription> GenericFunctionPtrDescription;
    std::shared_ptr<CTypeDescription> GenericDelegateClassDescription;

    SDecoratedTypeDescription GetInnerTypeDescription(EScriptInnerType InnerType);
    SDecoratedTypeDescription VoidTypeDescription;
    SDecoratedTypeDescription BoolTypeDescription;
    SDecoratedTypeDescription ByteTypeDescription;
    SDecoratedTypeDescription SbyteTypeDescription;
    SDecoratedTypeDescription ShortTypeDescription;
    SDecoratedTypeDescription UshortTypeDescription;
    SDecoratedTypeDescription Int32TypeDescription;
    SDecoratedTypeDescription Uint32TypeDescription;
    SDecoratedTypeDescription Int64TypeDescription;
    SDecoratedTypeDescription Uint64TypeDescription;
    SDecoratedTypeDescription CharTypeDescription;
    SDecoratedTypeDescription FloatTypeDescription;
    SDecoratedTypeDescription DoubleTypeDescription;
    SDecoratedTypeDescription DecimalTypeDescription;
    SDecoratedTypeDescription StringTypeDescription;
    SDecoratedTypeDescription ObjectTypeDescription; 
    //SDecoratedTypeDescription SharedObjectTypeDescription; //type of TSharedPtr<RObject>
    SDecoratedTypeDescription NullObjectTypeDescription;
    SDecoratedTypeDescription NullPtrTypeDescription;

    std::shared_ptr<CTypeDescription> FindClassByID(STypeID InTypeID);
    void AddScriptClass(std::shared_ptr<CTypeDescription> InClassDescription);
    
    //move Former before After
    void MoveScriptClassOrderFormer(
        std::shared_ptr<CTypeDescription> Former
        , std::shared_ptr<CTypeDescription> After  
    );

    TMap<STypeID,std::shared_ptr<CTypeDescription>> NativeClasses;
    TMap<STypeID,std::shared_ptr<CTypeDescription>> ScriptClasses;

    TVector<std::shared_ptr<CTypeDescription>> ScriptClassesInOrder;

    //the script classes that 
    //the function body is not filled
    TVector<std::shared_ptr<CTypeDescription>> ScriptNotFullyGenerializedClass;

    TMap<SGenericTypeArgumentGroup /* return type and parameters */
        , SDecoratedTypeDescription /* function type */  > FunctionTypeDescriptions;

    std::shared_ptr<CNamespaceDescription> FindOrAddChildeNamespace(std::shared_ptr<CNamespaceDescription> InParentNamespace, const TVector<CString> &SubPath);

    std::shared_ptr<CGSharpFieldDescription> FindFieldByName(std::shared_ptr<CTypeDescription> InClassDescription, const CString &InFieldName);

    //仅用于非泛化的类
    STypeID CreateNonGenerailizedTypeID(const TVector<CString>& InParentScopeNameChain,const CString& Name);


};
